package com.nervenets.web.controller.handler.admin.order;

import com.nervenets.utils.StringUtils;
import com.nervenets.web.controller.Global;
import com.nervenets.web.controller.handler.SessionHandler;
import com.nervenets.web.entity.MessageCode;
import com.nervenets.web.enumeration.*;
import com.nervenets.web.hibernate.domain.user.Order;
import com.nervenets.web.redis.domain.movie.MovieStored;
import com.nervenets.web.redis.domain.user.UserStored;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class TeamOrderListForManagerHandler extends SessionHandler<TeamOrderListForManagerParams> {
    @Override
    public ArrayList<Role> allowRoles() {
        return Role.dealer();
    }

    @Override
    public boolean needLog() {
        return false;
    }

    @Override
    public String handle(TeamOrderListForManagerParams params, HttpServletRequest request) throws Exception {
        String hql = "from Order where orderType = :orderType ";
        HashMap<String, Object> objects = new HashMap<>();
        objects.put("orderType", OrderType.movie);

        if (null != params.getPayType()) {
            hql += "and payType = :payType ";
            objects.put("payType", params.getPayType());
        }

        if (null != params.getStatus()) {
            hql += "and status = :status ";
            objects.put("status", params.getStatus());
        }

        if (params.getUnionId() > 0) {
            hql += "and unionId = :unionId ";
            objects.put("unionId", params.getUnionId());
        }

        if (params.getStartTime() > 0 && params.getEndTime() > 0 && params.getEndTime() > params.getStartTime()) {
            hql += "and createTime between :startTime and :endTime ";
            objects.put("startTime", params.getStartTime());
            objects.put("endTime", params.getEndTime());
        }

        try {
            if (!StringUtils.isEmpty(params.getOrderNumber())) {
                if (params.getOrderNumber().length() <= 12) return errorMessage(MessageCode.code_444, "订单号有误");
                hql += "and id = :id ";
                objects.put("id", Long.parseLong(params.getOrderNumber().substring(12)));
            }
        } catch (NumberFormatException e) {
            return errorMessage(MessageCode.code_444, "订单号有误");
        }

        if (!StringUtils.isEmpty(params.getKeyword())) {
            hql += "and extra like '%" + params.getKeyword() + "%' ";
        }

        ArrayList<Long> ids = new ArrayList<>();
        ids.add(params.getUserId());
        final List<Map<String, Object>> mapList = userDao.getTableBySql("select id from users where inviteUserId = ? or teamUserId = ?", new Object[]{params.getUserId(), params.getUserId()});
        for (Map<String, Object> map : mapList) {
            ids.add((Long) map.get("id"));
        }
        hql += "and userId in (:userIds) ";
        objects.put("userIds", ids);


        final BigDecimal countOfByHql = userDao.getCountOfByHql(hql, objects);
        BigDecimal actualPayMoney = userDao.getSumOfByHql(hql, "actualPayMoney", objects);
        hql += "order by id desc ";
        final List<Order> orders = userDao.getAllObjectsByHql(hql, objects, params.getStart(), params.getLimit());

        List<Model> models = new ArrayList<>();
        for (Order order : orders) {
            UserStored user = globalService.getUser(order.getUserId());
            final MovieStored movie = OrderType.movie.equals(order.getOrderType()) ? globalService.getMovie(order.getUnionId()) : null;
            models.add(new Model(order, user, movie));
        }

        return successMessage(models,
                new KeyValue("start", params.getStart()),
                new KeyValue("totalMoney", actualPayMoney.longValue()),
                new KeyValue("total", countOfByHql.intValue())
        );
    }

    @Override
    public String result() throws Exception {
        return successMessage(new Model());
    }

    @Data
    @NoArgsConstructor
    @AllArgsConstructor
    class Model {
        private long orderId;
        private String orderNumber;
        private int createTime;
        private int payTime;
        private PayType payType;
        private OrderStatus orderStatus;
        private long priceOfUnit;
        private int number;
        private boolean offlinePay;
        private long deposit;
        private int tailConfirmTime;//尾款确认时间，当为-1时，代表无尾款，为0时，代表未确认
        private String tailConfirmName;
        private List<String> tailConfirmImages;
        private Long profit;

        private String expressName;
        private String expressMobile;
        private String expressAddress;

        private String expressCompanyName;
        private String expressCompanyNumber;

        private long userId;
        private String userAvatar;
        private String userName;

        private long movieId;
        private String movieName;
        private String movieCoverImage;
        private MovieReleaseStatus movieReleaseStatus;

        public Model(Order order, UserStored user, MovieStored movie) {
            this.orderId = order.getId();
            this.orderNumber = Global.OrderNumber.getMBCreateNumber(order.getCreateTime(), order.getId());
            this.createTime = order.getCreateTime();
            this.payTime = order.getPayTime();
            this.payType = order.getPayType();
            this.orderStatus = order.getStatus();
            this.priceOfUnit = order.getExtra().getPriceOfUnit();
            this.number = order.getExtra().getNumber();
            this.offlinePay = order.isOfflinePay();
            this.deposit = order.getExtra().getDeposit();
            this.tailConfirmTime = order.getExtra().getTailConfirmTime();
            this.tailConfirmName = order.getExtra().getTailConfirmName();
            this.tailConfirmImages = order.getExtra().getTailConfirmImages();
            this.profit = order.getExtra().getProfit();

            this.expressName = order.getExtra().getName();
            this.expressMobile = order.getExtra().getMobile();
            this.expressAddress = order.getExtra().getAddress();

            this.expressCompanyName = order.getExtra().getExpressName();
            this.expressCompanyNumber = order.getExtra().getExpressNumber();

            this.userId = order.getUserId();
            this.userAvatar = user.getAvatar();
            this.userName = user.getName();

            if (null != movie) {
                this.movieId = order.getUnionId();
                this.movieName = movie.getTitle();
                this.movieCoverImage = movie.getCoverImage();
                this.movieReleaseStatus = movie.getReleaseStatus();
            }
        }
    }
}
